package com.fairytask.layer
{
	import com.fairytask.data.Modulator;
	import com.fairytask.data.battle.BattleData;
	import com.fairytask.define.ResDefine;
	import com.fairytask.engine.fileformat.pak.PakDecoder;
	import com.fairytask.objects.Cell;
	import com.fairytask.objects.Player;
	import com.fairytask.objects.Virus;
	import com.fairytask.resource.StaticIni;
	import com.fairytask.utils.TimeUtil;
	import com.fairytask.utils.Vec2D;
	
	import flash.display.Bitmap;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	
	import de.polygonal.ds.Itr;
	import de.polygonal.ds.ListSet;
	
	public class BattleLayer extends Sprite
	{
		private static var _instance	:BattleLayer;
		private var sceneData:Object;
		
		//本场景玩家数
		private var players:Vector.<Player>;
		private var model	:Modulator;
		private var rings		:Array=[];
		private var ringsContainer:Sprite;
		private var viruses:ListSet;
		private var cells:ListSet;
		private var curCell:Cell;
		private static var unitTypes:Vector.<Object>;
		private var difficulty:uint; //难度
		private var maxDifficulty:uint	=	20; //最高难度
		private var lineContainer:Sprite;
		private var selectedCells:Array;
		public var playerUnitType:int;
		private static var unitIdxArr	:Array	=	[];
		//显示
		private var sceneBg	:Bitmap;
		private var decoder:PakDecoder;
		private var readyToClear:Boolean;
		private var numPlayers:int;
		private var timeUtil:TimeUtil;
		private var mouseDownTime:Number;
		private var minMouseDownTime:Number=0.2;
		public var mouseDown:Boolean = false;
		private var maxSelectableCells:uint=8;
		public var isStart:Boolean = false;
		
		public static function get instance():BattleLayer
		{
			if(null==_instance)
			{
				_instance	=	new BattleLayer();
			}
			return _instance;
		}
		public function BattleLayer()
		{
			timeUtil	=	new TimeUtil();
			
			var imgLoader	:URLLoader	=	new URLLoader();
			imgLoader.dataFormat	=	URLLoaderDataFormat.BINARY;
			imgLoader.addEventListener(Event.COMPLETE,onLoaded);
			imgLoader.load(new URLRequest(ResDefine.SKIN_PATH+"bg/battle.pak"));
			
			model	=	Modulator.instance;
			ringsContainer	=	new Sprite();
			viruses	=	new ListSet();
			cells		=	new ListSet();
			players = new Vector.<Player>;
			unitTypes	=	new Vector.<Object>;
			lineContainer = new Sprite();
			selectedCells = [];
			
			lineContainer.mouseEnabled	=	false;
			lineContainer.mouseChildren = false;
			lineContainer.graphics.lineStyle(4, 0xffffff);
			
			addChild(lineContainer);
			addChild(ringsContainer);
			
			initEvent();
		}
		
		private function initEvent():void
		{
			addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
			addEventListener(MouseEvent.MOUSE_UP,onMouseUp);
		}
		
		/**
		 * 鼠标起 
		 * @param event
		 * 
		 */
		protected function onMouseUp(event:MouseEvent):void
		{
			mouseDown = false;
			if (!curCell)
			{
				while (selectedCells.length > 0)
				{
					
					selectedCells.pop();
				}
				return;
			}
			var cIndex:int = selectedCells.indexOf(curCell);
			if (cIndex != -1)
			{
				if (mouseDownTime < minMouseDownTime && curCell.unitType != players[0].unitType)
				{
					selectedCells.splice(cIndex, 1);
				}
				else if (mouseDownTime > minMouseDownTime && curCell.unitType == players[0].unitType)
				{
					selectedCells.splice(cIndex, 1);
				}
			}
			createClickRing(curCell);
			sendSelectedUnitsTo(curCell);
		}
		
		/**
		 * 转到目标 
		 * @param pCell
		 * 
		 */
		private function sendSelectedUnitsTo(pCell:Cell):void
		{
			var vCount:int = 0;
			if (selectedCells.indexOf(pCell) != -1)
			{
				return;
			}
			var tmpCount:int = 0;
			while (tmpCount < selectedCells.length)
			{
				vCount = Math.round(selectedCells[tmpCount].numUnits / 2);
				createViruses(selectedCells[tmpCount], pCell, vCount);
				selectedCells[tmpCount].numUnits = selectedCells[tmpCount].numUnits - vCount;
				tmpCount++;
			}
			while (selectedCells.length > 0)
			{
				selectedCells.pop();
			}
		}
		
		/**
		 * 鼠标按下 
		 * @param event
		 * 
		 */
		protected function onMouseDown(event:MouseEvent):void
		{
			var cIndex:int = 0;
			mouseDown = true;
			if (!curCell)
			{
				return;
			}
			if (curCell.unitType == players[0].unitType)
			{
				cIndex = selectedCells.indexOf(curCell);
				if (cIndex == -1)
				{
					if (selectedCells.length < maxSelectableCells)
					{
						selectedCells.push(curCell);
					}
				}
				else
				{
					selectedCells.splice(cIndex, 1);
				}
			}
		}
		
		/**
		 * 资源加载完毕 
		 * @param event
		 * 
		 */
		protected function onLoaded(event:Event):void
		{
			decoder	=	new PakDecoder(event.target.data);
			decoder.addEventListener(Event.COMPLETE,function(evt:Event):void
			{
				sceneBg	=	new Bitmap(evt.target.result[0]);
				addChildAt(sceneBg,0);
			});
			decoder.decode();
		}
		
		/**
		 * 根据ID来完成场景搭建 
		 * @param pSid
		 * 
		 */
		public function initById(pData:BattleData):void
		{
			isStart		=	true;
			sceneData		=	StaticIni.getIniObj(pData.bid);
			numPlayers	=	sceneData["Players"];
			playerUnitType	=	pData.playerUnitType;
			var tmpUtypes	:Array	=	sceneData.UnitTypes.split(",");
			var tmpUnitObj	:Object;
			var tmpUnitId		:int;
			while(tmpUtypes.length>0)
			{
				tmpUnitId	=	tmpUtypes.shift();
				tmpUnitObj	=	StaticIni.getIniObj(tmpUnitId.toString());
				unitTypes.push(tmpUnitObj);
				unitIdxArr.push(tmpUnitId);
			}
			
			difficulty = 1 + Math.random() * maxDifficulty;
			
			//取得列表
			var cellList	:Array	=	sceneData["CellListID"].split(",");
			while(cellList.length>0)
			{
				var tmpData	:Object	=	StaticIni.getIniObj(cellList.shift());
				var cell	:Cell	=	new Cell(tmpData.skin);
				cell.x	=	tmpData.x;
				cell.y	=	tmpData.y;
				cell.init(Number(tmpData.Scale));
				addChild(cell);
				cells.set(cell);
				
				cell.isStart	=	int(tmpData.isStart);
				//创建当前玩家
				if(int(tmpData.isStart)==1)
				{
					if(players.length==0)
					{
						createPlayer(pData.playerUnitType,pData.numUnits,false);
					}
					else
					{
						createPlayer(pData.playerUnitType,pData.numUnits,false);
					}
					cell.unitType	=	pData.playerUnitType;
					cell.numUnits	=	pData.numUnits;
				}
				else
				{
					cell.numUnits = Math.round(cell.maxUnits * difficulty / maxDifficulty * 0.1);
					cell.unitType	=	-1;
				}
			}
		}
		
		/**
		 * 添加玩家 
		 * @param pUnitType
		 * @param pNum
		 * @param pAi
		 * 
		 */
		public function createPlayer(pUnitType:int,pNum:int,pAi:Boolean=true):void
		{
			var tmpPlayer	:Player;
			for (var i:int = 0; i < numPlayers; i++) 
			{
				tmpPlayer	=	new Player();
				tmpPlayer.numUnits	=	pNum;
				tmpPlayer.unitType	=	pUnitType;
				tmpPlayer.isAI	=	pAi;
				players.push(tmpPlayer);
			}
		}
		
		/**
		 * 是否为自己的 
		 * @return 
		 * 
		 */
		public function isOwer(pCell:Cell):Boolean
		{
			return pCell.unitType==playerUnitType;
		}
		
		/**
		 * 创建Cell的外圈 
		 * @param pCell
		 * 
		 */
		public function createClickRing(pCell:Cell) : void
		{
			/*if (!pCell)
			{
				return;
			}
			var tmpRing:MovieClip = AssetManager.instance.getMovieClip("ring_001");
			tmpRing.x = pCell.x;
			tmpRing.y = pCell.y;
			tmpRing.width = pCell.radius * 3;
			tmpRing.height = pCell.radius * 3;
			ringsContainer.addChild(tmpRing);
			rings.push(tmpRing);*/
		}
		
		public function getUnitTypes() : Vector.<Object>
		{
			return unitTypes;
		}
		
		public static function getUnitType(pType:int) : Object
		{
			var tmpIdx:int	=	unitIdxArr.indexOf(pType);
			if (tmpIdx >= unitTypes.length || tmpIdx < 0)
			{
				return null;
			}
			return unitTypes[tmpIdx];
		}
		
		/**
		 * 取得难度 
		 * @return 
		 */
		public function get diff() : uint
		{
			return difficulty;
		}
		
		/**
		 * 设置难度 
		 * @param param1
		 * 
		 */
		public function set diff(pDiff:uint) : void
		{
			difficulty = pDiff;
			if (difficulty < 1)
			{
				difficulty = 1;
			}
			else if (difficulty >= maxDifficulty)
			{
				difficulty = maxDifficulty;
			}
		}
		/**
		 * 取得最大难度 
		 * @return 
		 * 
		 */
		public function get maxDiff() : uint
		{
			return maxDifficulty;
		}
		/**
		 * 取得所有玩家 
		 * @return 
		 * 
		 */
		public function get allPlayers() : Vector.<Player>
		{
			return players;
		}
		
		/**
		 * 生成病毒  
		 * @param fCell
		 * @param tCell
		 * @param pCount
		 * 
		 */
		public function createViruses(fCell:Cell, tCell:Cell, pCount:uint = 20) : void
		{
			var tmpVirus:Virus = null;
			var tmpVec:Vec2D = null;
			while (pCount>0)
			{
				tmpVirus = new Virus();
				tmpVec = fCell.randVec;
				tmpVirus.x = tmpVec.x;
				tmpVirus.y = tmpVec.y;
				tmpVirus.fromCell = fCell;
				tmpVirus.toCell = tCell;
				tmpVirus.unitType = fCell.unitType;
				addChild(tmpVirus);
				viruses.set(tmpVirus);
				fCell.vel = fCell.vel + (1 - fCell.radius / 100) * tmpVirus.value * 0.5;
				fCell.ov.vec = tmpVirus.ov;
				pCount--;
			}
			
		}
		
		/**
		 * 清除所有 
		 * 
		 */
		public function clearAll():void
		{
			var tmpSList	:Itr	=	cells.iterator();
			while(tmpSList.hasNext())
			{
				var tmpCell:Cell	=	tmpSList.next() as Cell;
				tmpCell.selected	=	false;
			}
			
			cells.clear();
			lineContainer.graphics.clear();
			lineContainer.graphics.lineStyle(4, 0xffffff);
			readyToClear = false;
		}
		
		/**
		 * 更新各物件状态 
		 * @param elapsed
		 * @param dt
		 * 
		 */
		public function update(elapsed:uint, dt:Number):void
		{
			var tmpCell:Cell=null;
			var tmpPlayer:Player;
			var virusIterator:Itr=null;
			var tmpVirus:Virus=null;
			var cellIterator:Itr=null;
			var subVec:Vec2D=null;
			var rSquard:Number=0;
			var loc12:Itr=null;
			var secCell:Cell=null;
			var radiuPlus:Number=0;
			var mouseVec:Vec2D=null;
			var loc19:Vec2D=null;
			var loc20:Vec2D=null;
			
			for each (tmpPlayer in players) 
			{
				tmpPlayer.numCell = 0;
				tmpPlayer.numUnits = 0;
			}
			virusIterator = viruses.iterator();
			while (virusIterator.hasNext()) 
			{
				(tmpVirus = virusIterator.next() as Virus).updateMove(dt);
				cellIterator = cells.iterator();
				while (cellIterator.hasNext()) 
				{
					subVec = ( (tmpCell = cellIterator.next() as Cell).vec).subVec(tmpVirus.posV);
					rSquard = tmpCell.radius * tmpCell.radius;
					if (subVec.len2 <= rSquard + tmpVirus.feelerDist) 
					{
						if (tmpCell != tmpVirus.toCell) 
						{
							if (tmpCell != tmpVirus.fromCell) 
							{
								tmpVirus.veerFrom(subVec, rSquard, subVec.len2);
							}
						}
						else if (subVec.len2 <= rSquard) 
						{
							tmpCell.ov = tmpVirus.ov.vec;
							tmpCell.vel = tmpCell.vel + (1 - tmpCell.radius / 100) * tmpVirus.value;
							if (tmpCell.unitType == tmpVirus.unitType) 
							{
								tmpCell.numUnits = tmpCell.numUnits + tmpVirus.value;
							}
							else 
							{
								tmpCell.numUnits = tmpCell.numUnits - tmpVirus.value;
								if (tmpCell.numUnits <= 0) 
								{
									tmpCell.numUnits = 0;
									tmpCell.unitType = tmpVirus.unitType;
									createClickRing(tmpCell);
									tmpCell.playScaleEffect();
								}
							}
							if (contains(tmpVirus)) 
							{
								removeChild(tmpVirus);
							}
							virusIterator.remove();
							//virusIterator.reset();
						}
					}
				}
				for each (tmpPlayer in players) 
				{
					if (tmpVirus.unitType != tmpPlayer.unitType) 
					{
						continue;
					}
					tmpPlayer.numCell++;
				}
				tmpVirus.update(dt);
			}
			curCell = null;
			cellIterator = cells.iterator();
			while (cellIterator.hasNext()) 
			{
				tmpCell = cellIterator.next() as Cell;
				loc12 = cells.iterator();
				while (loc12.hasNext()) 
				{
					secCell = loc12.next() as Cell;
					if (tmpCell != secCell) 
					{
						subVec = tmpCell.vec.subVec(secCell.vec);
						radiuPlus = tmpCell.radius + secCell.radius;
						if (subVec.len2 <= radiuPlus * radiuPlus + 2) 
						{
							tmpCell.ov.angle = subVec.angle;
							secCell.ov.angle = subVec.reverse.angle;
							tmpCell.vel = (1 - subVec.len2 / (radiuPlus * radiuPlus)) * 100 + 1;
							secCell.vel = (1 - subVec.len2 / (radiuPlus * radiuPlus)) * 100 + 1;
						}
					}
				}
				for each (tmpPlayer in players) 
				{
					if (tmpCell.unitType != tmpPlayer.unitType) 
					{
						continue;
					}
					tmpPlayer.numCell++;
				}
				if (difficulty / maxDifficulty > 0.8) 
				{
					if (!(tmpCell.unitType == -1) && !(tmpCell.unitType == players[0].unitType)) 
					{
						tmpCell.showUnits = false;
					}
					else 
					{
						tmpCell.showUnits = true;
					}
				}
				tmpCell.updateMove(elapsed, dt);
				if (tmpCell.hitTestPoint(mouseX, mouseY, true)) 
				{
					curCell = tmpCell;
				}
			}
			var lostCount:uint=0;
			for each (tmpPlayer in players) 
			{
				tmpPlayer.update(elapsed, dt);
				if (!tmpPlayer.hasLost()) 
				{
					continue;
				}
				++lostCount;
			}
			if (players[0].hasLost()) 
			{
				endMap(false);
				return;
			}
			if (lostCount >= (players.length - 1) && !players[0].hasLost()) 
			{
				endMap();
				return;
			}
			if (mouseDown) 
			{
				mouseDownTime = mouseDownTime + dt;
			}
			else 
			{
				mouseDownTime = 0;
			}
			if (readyToClear) 
			{
				lineContainer.graphics.clear();
				lineContainer.graphics.lineStyle(4, 10066329);
				readyToClear = false;
			}
			if (curCell) 
			{
				if (curCell.unitType == players[0].unitType || selectedCells.length > 0) 
				{
					lineContainer.graphics.drawCircle(curCell.x, curCell.y, curCell.radius + 5);
					readyToClear = true;
				}
				if (mouseDownTime > minMouseDownTime && curCell.unitType == players[0].unitType && selectedCells.length > 0 && selectedCells.indexOf(curCell) == -1 && selectedCells.length < maxSelectableCells) 
				{
					selectedCells.push(curCell);
					createClickRing(curCell);
				}
			}
			for each (tmpCell in selectedCells) 
			{
				readyToClear = true;
				if (tmpCell != curCell) 
				{
					lineContainer.graphics.drawCircle(tmpCell.x, tmpCell.y, tmpCell.radius + 5);
				}
				if (tmpCell.unitType != players[0].unitType) 
				{
					selectedCells.splice(selectedCells.indexOf(tmpCell), 1);
				}
				if (curCell) 
				{
					mouseVec = curCell.vec;
					loc20 = tmpCell.vec.subVec(mouseVec);
					(loc19 = tmpCell.vec.subVec(mouseVec)).normalize();
					loc20.normalize();
					loc19.mulN(tmpCell.radius + 5);
					loc20.mulN(curCell.radius + 5);
					lineContainer.graphics.moveTo(tmpCell.x - loc19.x, tmpCell.y - loc19.y);
					lineContainer.graphics.lineTo(mouseVec.x + loc20.x, mouseVec.y + loc20.y);
					continue;
				}
				mouseVec = new Vec2D(mouseX, mouseY);
				(loc19 = tmpCell.vec.subVec(mouseVec)).normalize();
				loc19.mulN(tmpCell.radius + 5);
				lineContainer.graphics.moveTo(tmpCell.x - loc19.x, tmpCell.y - loc19.y);
				lineContainer.graphics.lineTo(mouseVec.x, mouseVec.y);
			}
		}
		
		private function endMap(isUser:Boolean=true):void
		{
			// TODO Auto Generated method stub
			
		}
		
		public function show():void
		{
			// TODO Auto Generated method stub
			
		}
	}
}